home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
docs
/
ippon
/
data
/
etc
/
sword.lzh
/
enemy.c
next >
Wrap
C/C++ Source or Header
|
1999-06-03
|
5KB
|
253 lines
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <XSP2lib.H>
#include "main.h"
#include "enemy.h"
#include "fxsp2lib.h"
#include "parts.h"
#define ENEMY_MAX 64 /* 最大数 */
static ENEMY enemy[ENEMY_MAX]; /* ワーク */
static ENEMY *enemy_top, /* 使用中のワークのリスト */
*enemy_null_top, /* 空のワークのリスト */
*enemy_end; /* 使用中ワークのリストの末尾 */
extern char end_of_data;
extern char f_option_flag;
typedef struct _spwork {
signed short x, y; /* 座標 */
unsigned short pt; /* スプライトパターンNo. */
unsigned short info; /* 反転コード・色・優先度を表わすデータ */
} SPWORK;
int EnemyInit0 (void)
{
int i;
/* リストをつなげる */
enemy_top = NULL;
enemy_end = NULL;
enemy_null_top = enemy;
for (i = 0; i < ENEMY_MAX; i++)
enemy[i].next = &enemy[i + 1];
enemy[ENEMY_MAX - 1].next = NULL;
return (0);
}
void EnemyInit (unsigned short type, unsigned short info,
signed short ox, signed short oy, ENEMY * parent)
{
ENEMY *p;
if (enemy_null_top == NULL) {
printf ("ワークが一杯です\n");
return; /* 空きのワークがない(キャラクターオーバー) */
}
/* リストの末尾に新しいノードを追加 */
p = enemy_null_top;
enemy_null_top = p->next;
if (enemy_top == NULL)
enemy_top = p;
else
enemy_end->next = p;
p->next = NULL;
enemy_end = p;
p->type = type;
p->info = info;
p->ox = ox;
p->oy = oy;
p->x = p->y = 0;
p->parent = parent;
p->lx = p->ly = p->lz = 0.0;
p->vx = p->vy = p->vz = 0.0;
p->cyc = 0;
p->cyc1 = 0;
p->round = p->round_v = p->spring = p->spring_v = 0.0;
switch (type) {
case 1:
case 2:
p->round = M_PI / 2.0;
break;
}
}
/* 複数のスプライトで構成されているパーツ1個分のスプライトをまとめて表示 */
static void DispSp (ENEMY * p, short sp_num, PARTS_TABLE * parts_table)
{
short h;
SPWORK spwork;
for (h = 0; h < sp_num; h++) {
p->x = p->lx + p->ox;
p->y = p->ly + p->oy;
if (p->parent != NULL) {
spwork.x = p->x + p->parent->x + parts_table[h].x;
spwork.y = p->y + p->parent->y + parts_table[h].y;
} else {
spwork.x = p->x + parts_table[h].x;
spwork.y = p->y + parts_table[h].y;
}
spwork.pt = parts_table[h].pt;
spwork.info = p->info;
spwork.x += (128 + 16); /* 表示用に補正 */
spwork.y += (128 + 16);
xsp_set_st (&spwork);
fxsp_set_st (&spwork);
spwork.x -= (128 + 16);
spwork.y -= (128 + 16);
}
}
void EnemyMove (void)
{
ENEMY *p, *q;
p = enemy_top;
q = NULL;
while (p != NULL) {
char erase_flag = 0;
switch (p->type) {
case 0: /* 本体 */
DispSp (p, 18, parts0_table);
break;
case 1: /* 左翼 */
switch (p->cyc) {
#define R1 8 /* 半径 */
#define RA1 (0.04) /* 加速度 */
#define RV1_MAX (0.3) /* 速度最大値 */
case 0:/* 回転 */
p->round += p->round_v;
if ((p->round_v += RA1) > RV1_MAX)
p->round_v = RV1_MAX;
p->lx = R1 * cos (p->round);
p->ly = R1 * sin (p->round);
#define R1_MAX (M_PI)
if (p->round > R1_MAX) {
p->round -= R1_MAX;
p->cyc++;
}
break;
case 1:/* ばね振動 */
#define SPRING_K1 0.5
#define SPRING_M1 0.8 /* 摩擦計数 */
#define ROUND_MIN1 0.03 /* 座標がこれ以下になれば中断 */
#define ROUNDV_MIN1 0.10 /* 速度がこれ以下になれば中断 */
p->round += p->round_v;
p->round_v -= SPRING_K1 * p->round;
p->round_v *= SPRING_M1;
if ((fabs (p->round) < ROUND_MIN1) && (fabs (p->round_v) < ROUNDV_MIN1))
p->cyc++;
p->lx = R1 * cos (R1_MAX + p->round);
p->ly = R1 * sin (R1_MAX + p->round);
break;
case 2:
p->lx = R1 * cos (R1_MAX + p->round);
p->ly = R1 * sin (R1_MAX + p->round);
break;
default:
break;
}
DispSp (p, 9, parts1_table);
break;
case 2: /* 右翼 */
switch (p->cyc) {
case 0:/* 回転 */
p->round += p->round_v;
if ((p->round_v += RA1) > RV1_MAX)
p->round_v = RV1_MAX;
p->lx = -R1 * cos (p->round);
p->ly = R1 * sin (p->round);
if (p->round > R1_MAX) {
p->round -= R1_MAX;
p->cyc++;
}
break;
case 1:/* ばね振動 */
p->round += p->round_v;
p->round_v -= SPRING_K1 * p->round;
p->round_v *= SPRING_M1;
if ((fabs (p->round) < ROUND_MIN1) && (fabs (p->round_v) < ROUNDV_MIN1))
p->cyc++;
p->lx = -R1 * cos (R1_MAX + p->round);
p->ly = R1 * sin (R1_MAX + p->round);
break;
case 2:
p->lx = -R1 * cos (R1_MAX + p->round);
p->ly = R1 * sin (R1_MAX + p->round);
end_of_data = !0;
break;
default:
break;
}
DispSp (p, 9, parts2_table);
break;
default:
printf ("enemy_move() : バグってます\n");
break;
}
if (erase_flag) {
if (q == NULL) { /* リストの一番最初を削除 */
enemy_top = p->next;
p->next = enemy_null_top;
enemy_null_top = p;
q = NULL;
p = enemy_top;
} else {
if (p == enemy_end) { /* リストの一番最後を削除 */
q->next = NULL;
enemy_end = q;
p->next = enemy_null_top;
enemy_null_top = p;
p = q->next;
} else {
q->next = p->next;
p->next = enemy_null_top;
enemy_null_top = p;
p = q->next;
}
}
} else {
q = p;
p = p->next;
}
}
}
void EnemyTini (void)
{
int i;
/* リストをつなげる */
enemy_top = NULL;
enemy_null_top = enemy;
for (i = 0; i < ENEMY_MAX; i++)
enemy[i].next = &enemy[i + 1];
enemy[ENEMY_MAX - 1].next = NULL;
}